<?PHP
namespace SDF\Lib\Goods;

use MongoDB\BSON\UTCDateTime;
use MongoDB\Driver\WriteConcern;
use SDF\Db\MongoDb;

/**
 * Class goods_category 商品类目
 * @package SDF\Lib\Goods
 */
class goods_category extends MongoDb {
    private static $tree_arr = [];//缓存的目录树，避免重复读取数据库
    /**
     * 授权构造
     * special_auth constructor.
     */
    public function __construct(){
        parent::__construct('goods_category', 'goods');
    }

    /**
     * 创建类目
     * @param $document
     * @param array $options
     * @param WriteConcern|NULL $writeConcern
     * @return array
     * @throws \Exception
     */
    public function insertOne(&$document, array $options = [], WriteConcern $writeConcern = NULL){
        if(empty($document['name'])){
            throw new \Exception('name is null');
        }
        if(isset($document['p_id'])){
            throw new \Exception('p_id not set');
        }
        $data = array(
            "name" => $document['name'],//类目名
            "p_id" => self::format(0),//上级id
            "attr" => [],//类目属性
            "create_time" => new UTCDateTime(),//创建时间
            "update_time" => new UTCDateTime(),//更新时间
            "goods_count" => 0,//类目商品数量，默认0，需要在类目管理页面手动刷新
            "status" => 0,//类目状态，1可用，0禁用，-1删除。
            "sort" => 100,//排序
            "def_icon" => "",//类目大图标url
            "cur_icon" => "",//类目小图标url
        );
        parent::insertOne($data, $options, $writeConcern);
        return $data;
    }

    /**
     * 将数据格式化成树形结构
     * @author Xuefen.Tong
     * @param array $items
     * @return array
     */
    private static function format_tree($items) {
        $tree = array();
        foreach ($items as $item)
            if (isset($items[$item->p_id.'']))
                $items[$item->p_id.'']->son[] = &$items[$item->_id.''];
            else
                $tree[] = &$items[$item->_id.''];
        return $tree;
    }

    /**
     * 获取类目树
     * @param int $status 获取不同状态的目录树。1：只获取可用的目录树，0 获取可用与禁用的目录树。 -1 获取所有目录树,包括已删除的。
     * @param array $projection 需要显示的字段
     * @return mixed
     */
    public function getTree($status = 1,$projection = array('p_id'=>true,'name'=>true)){
        $status = intval($status);
        if(!empty(self::$tree_arr[$status])){
            return self::$tree_arr[$status];
        }
        $iten = $this->getList($status,$projection,'_id');
        self::$tree_arr[$status] = self::format_tree($iten);
        return self::$tree_arr[$status];
    }

    /**
     * * 获取类目列表
     * @param int $status 获取不同状态的目录树。1：只获取可用的目录树，0 获取可用与禁用的目录树。 -1 获取所有目录树,包括已删除的。
     * @param array $projection 需要的字段
     * @param string $use_keys 使用迭代器元素键作为索引。默认私用_id，如果你不需要，可用传入一个空值。
     * @return array
     */
    public function getList($status = 0,$projection = [],$use_keys = '_id'){
        $status = intval($status);
        $filter = array('status'=>['$gte' => $status]);
        $ls = parent::find($filter, $projection,0,0,array('sort'=>-1))->toArray();
        if (empty($use_keys)){
            return $ls;
        }
        $list = [];
        foreach ($ls as $vo){
            $key = is_object($vo->{$use_keys})?$vo->{$use_keys}.'':$vo->{$use_keys};
            $list[$key] = $vo;
        }
        return $list;
    }

}